package com.zhousb.file_retrieval_server.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zhousb.file_retrieval_server.domain.dto.UserAddDto;
import com.zhousb.file_retrieval_server.domain.dto.UserRoleDto;
import com.zhousb.file_retrieval_server.domain.dto.UserRoleSimpleDto;
import com.zhousb.file_retrieval_server.domain.entity.SysRole;
import com.zhousb.file_retrieval_server.domain.entity.SysUser;
import com.zhousb.file_retrieval_server.domain.entity.SysUserRole;
import com.zhousb.file_retrieval_server.domain.so.SimpleSo;
import com.zhousb.file_retrieval_server.domain.vo.SysUserVo;
import com.zhousb.file_retrieval_server.domain.vo.UserSimpleVo;
import com.zhousb.file_retrieval_server.mapper.SysUserMapper;
import com.zhousb.file_retrieval_server.mapper.SysUserRoleMapper;
import com.zhousb.file_retrieval_server.security.JwtUser;
import com.zhousb.file_retrieval_server.service.SysUserService;
import com.zhousb.file_retrieval_server.utils.AuthUtils;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class SysUserServiceImpl implements SysUserService {

    @Resource
    private SysUserMapper sysUserMapper;
    @Resource
    AuthUtils authUtils;

    Map<String,List<Long>> roleUserMap = new HashMap<>();
    Map<String,String> userMap = new HashMap<>();

    @PostConstruct
    public void init() {
        initRoleUserMap();
        initUserMap();
    }

    @Override
    public SysUser getByUsername(String username) {




        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<SysUser>()
                .eq(SysUser::getUserName, username);
        return sysUserMapper.selectOne(queryWrapper);
    }

    @Override
    public SysUser getById(Long userId) {
        return sysUserMapper.selectById(userId);
    }

    @Override
    public boolean updateUser(SysUser sysUser) {
        return true;
    }

    @Override
    public boolean addUser(UserAddDto dto) {
        SysUser sysUser = new SysUser();
        BeanUtils.copyProperties(dto, sysUser);
        sysUser.setTenantId(Long.parseLong(dto.getTenantId()));
        sysUser.setPassword(authUtils.passwordEncoder().encode(dto.getPassword()));
        return sysUserMapper.insert(sysUser) > 0;
    }

    @Override
    public List<SysRole> listRoleByUserId(Long userId) {
        return sysUserMapper.listRoleByUserId(userId);
    }

    /**
     * 根据条件查询用户列表
     *
     * @param page 分页参数
     * @param so   查询条件
     * @return 用户列表
     */
    @Override
    public IPage<SysUserVo> listUser(Page page, SimpleSo so) {
        JwtUser jwtUser = authUtils.getUser();
        boolean isSuperAdmin = authUtils.isSuperAdmin();
        IPage<SysUserVo> sysUsers = sysUserMapper.pageUser(page, so.getKeyword());
        return sysUsers;
    }


    @Override
    public JwtUser getUserInfo() {
        return authUtils.getUser();
    }

    @Override
    public boolean deleteUser(Long userId) {
        sysUserMapper.deleteById(userId);
        return false;
    }

    @Resource
    private SysUserRoleMapper sysUserRoleMapper;

    @Transactional
    @Override
    public boolean saveRole(UserRoleDto dto) {
        List<Long> roleIds = dto.getRoleIds();
        sysUserRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getUserId, dto.getUserId()));
        roleIds.forEach(roleId -> {
            SysUserRole sysUserRole = new SysUserRole();
            sysUserRole.setUserId(dto.getUserId());
            sysUserRole.setRoleId(roleId);
            sysUserRoleMapper.insert(sysUserRole);
        });
        return true;
    }

    @Override
    public List<UserSimpleVo> listAll() {
        List<UserSimpleVo> result = new ArrayList<>();
        List<SysUser> user = sysUserMapper.selectList(null);
        result = user.stream().map(s->{
            UserSimpleVo vo = new UserSimpleVo();
            vo.setUserId(s.getId());
            vo.setRealName(s.getRealName());
            return vo;
        }).toList();
        return result;
    }

    @Override
    public List<Long> getRoleUserMap(String roleCode) {
        if(roleUserMap == null || roleUserMap.isEmpty()){
            initRoleUserMap();
        }
        return roleUserMap.get(roleCode);
    }

    @Override
    public boolean updatePassword(String password) {
        JwtUser jwtUser = authUtils.getUser();
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        final String passHash = encoder.encode(password);
        System.out.println(passHash);
        LambdaUpdateWrapper<SysUser> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(SysUser::getPassword,passHash).eq(SysUser::getId,jwtUser.getUserId());
        sysUserMapper.update(updateWrapper);
        return true;
    }

    @Override
    public String getRealName(String userId) {
        String realName = userMap.get(userId);
        if(!StringUtils.hasText(realName)){
            initUserMap();
            realName = userMap.get(userId);
            if(StringUtils.hasText(realName)){
                return realName;
            }else{
                return "未知";
            }
        }else{
            return realName;
        }
    }

    private void initRoleUserMap(){
        List<UserRoleSimpleDto> userList = sysUserMapper.listUserRoles();
        roleUserMap = userList.stream().collect(Collectors.groupingBy(UserRoleSimpleDto::getRoleCode, Collectors.mapping(UserRoleSimpleDto::getUserId,Collectors.toList())));
    }

    private void initUserMap(){
        List<SysUser> userList = sysUserMapper.selectList(null);
        userMap = userList.stream().collect(Collectors.toMap(sysUser ->String.valueOf(sysUser.getId()), SysUser::getRealName));
    }



    public static void main(String[] args) {
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        final String passHash = encoder.encode("123");
        System.out.println(passHash);
    }
}
